package genesis.familytree.server.modules.home.service.impl;

import genesis.familytree.server.common.utils.FormterUtils;
import genesis.familytree.server.common.utils.InfoCoverUtils;
import genesis.familytree.server.common.utils.StringUtils;
import genesis.familytree.server.modules.common.exception.AuthCodeErrorException;
import genesis.familytree.server.modules.common.exception.ParamNullException;
import genesis.familytree.server.modules.home.dao.IHomeUserDao;
import genesis.familytree.server.modules.home.dao.IHomeUserWechatDao;
import genesis.familytree.server.modules.home.entity.HomeRelate;
import genesis.familytree.server.modules.home.entity.HomeUser;
import genesis.familytree.server.modules.home.entity.HomeUserWechat;
import genesis.familytree.server.modules.home.exception.IdCardNumberErrorException;
import genesis.familytree.server.modules.home.service.IHomeRelateService;
import genesis.familytree.server.modules.home.service.IHomeUserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import wechat.controller.WechatSupport;
import wechat.vo.UserAccessTokenResponse;
import wechat.vo.UserInfo;
import wechat.vo.UserRefreshTokenResponse;
import wechat.vo.WeChatAccount;

import javax.annotation.Resource;
import java.util.List;

/**
 * Created by coderjiang@sina.com on 2016/7/8.
 */
@Transactional(readOnly = true)
@Service
public class HomeUserServiceImpl implements IHomeUserService {

    private WeChatAccount account;

    @Resource
    private IHomeUserDao dao;

    @Resource
    private IHomeUserWechatDao wechatDao;

    @Override
    @Transactional(readOnly = false)
    public HomeUserWechat registerFromWechat(WechatSupport support, String code) {
        this.account = support.getWeChatCore().getAccount();

        // 第二步：通过code换取网页授权access_token
        UserAccessTokenResponse userAccessToken = support.getUserAccessToken(code);

        // 第三步：刷新access_token（如果需要）
        UserRefreshTokenResponse refreshTokenResponse = account.refreshToken(userAccessToken.getRefresh_token());

        // 第四步：拉取用户信息(需scope为 snsapi_userinfo)
        UserInfo userInfo = account.getUserInfo(userAccessToken.getAccess_token(), userAccessToken.getOpenid(), "zh_CN");

        HomeUserWechat homeUserWechat = this.getHomeUserWechatByOpenID(userAccessToken.getOpenid());
        if (homeUserWechat == null) {
            homeUserWechat = this.addHomeUserWeChat(userAccessToken, refreshTokenResponse, userInfo);
        }
        return homeUserWechat;
    }

    @Override
    @Transactional(readOnly = false)
    public HomeUserWechat addHomeUserWeChat(UserAccessTokenResponse userAccessToken, UserRefreshTokenResponse refreshTokenResponse, UserInfo userInfo) {
        HomeUserWechat homeUserWechat = new HomeUserWechat();
        homeUserWechat.setOpenId(userAccessToken.getOpenid());
        homeUserWechat.setExpiresIn(userAccessToken.getExpires_in());
        homeUserWechat.setScope(userAccessToken.getScope());
        homeUserWechat.setUnionid(userAccessToken.getUnionid());
        homeUserWechat.setNickname(userInfo.getNickname());
        homeUserWechat.setSex(userInfo.getSex());
        homeUserWechat.setProvince(userInfo.getProvince());
        homeUserWechat.setCity(userInfo.getCity());
        homeUserWechat.setCountry(userInfo.getCountry());
        homeUserWechat.setHeadimgurl(userInfo.getHeadimgurl());
        homeUserWechat.setPrivilege(userInfo.getPrivilege());
        this.wechatDao.saveOne(homeUserWechat);
        return homeUserWechat;
    }

    @Override
    @Transactional(readOnly = false)
    public HomeUserWechat addHomeUserWechat(HomeUserWechat homeUserWechat) {
        this.wechatDao.saveOne(homeUserWechat);
        return homeUserWechat;
    }

    @Override
    public HomeUser findByOpenID(String openId) {
        return this.dao.getHomeUserByOpenID(openId);
    }

    @Override
    @Transactional(readOnly = false)
    public HomeUser addHomeUser(String nickname, String mobile, String fullname, String idcard, String code, String smsCode, String openID) throws AuthCodeErrorException, IdCardNumberErrorException {

        if(!code.equals(smsCode)){
            throw new AuthCodeErrorException("短信认证吗错误");
        }

        if(!FormterUtils.isIDCard(idcard)){
            throw new IdCardNumberErrorException("身份证号码格式不正确");
        }


        HomeUser homeUser = new HomeUser();
        homeUser.setNickname(nickname);
        homeUser.setMobile(mobile);
        homeUser.setRealName(fullname);
        homeUser.setIdCard(idcard);
        homeUser.setHomeUserWechat(this.getHomeUserWechatByOpenID(openID));
        this.dao.addHomeUser(homeUser);

        return homeUser;
    }

    @Override
    public HomeUser getHomeUserByUserID(int userID) {
        return coverInfo(this.dao.getHomeUserByUserID(userID));
    }

    @Override
    public HomeUser getOne(String idcard, String mobile) {

        HomeUser homeUser = null;
        if(StringUtils.isNotBlank(idcard)){
            homeUser = this.dao.getHomeUserByIdcard(idcard);
        }
        if(StringUtils.isNotBlank(mobile) && homeUser == null){
            homeUser = this.dao.getHomeUserByMobile(mobile);
        }
        return  homeUser;
    }

    @Override
    public HomeUser addHomeUser(String fullname, String idcard, String mobile) {
        HomeUser homeUser = new HomeUser();
        homeUser.setRealName(fullname);
        homeUser.setIdCard(idcard);
        homeUser.setMobile(mobile);
        this.dao.addHomeUser(homeUser);
        return homeUser;
    }

    /**
     * 隐藏部分敏感信息
     * @param homeUserByUserID
     * @return
     */
    private HomeUser coverInfo(HomeUser homeUserByUserID) {
        homeUserByUserID.setIdCard(InfoCoverUtils.coverIdCard(homeUserByUserID.getIdCard()));
        homeUserByUserID.setMobile(InfoCoverUtils.coverMobile(homeUserByUserID.getMobile()));
        return homeUserByUserID;
    }


    @Override
    public HomeUser getHomeUserByOpenID(String openID) {
        return this.dao.getHomeUserByOpenID(openID);
    }

    @Override
    public HomeUserWechat getHomeUserWechatByOpenID(String openid) {
        return this.wechatDao.getHomeUserWeChatByOpenID(openid);
    }


}
